<template>
  <!-- 添加环境弹窗 -->
  <Modal v-model="modalVisible" :title="clone ? '克隆服务' : isEdit ? '编辑服务' : '添加服务'" width="800px" :mask-closable="false" @on-cancel="serviceAddCancel">
    <div class="modal-add">
      <Form :model="serviceForm" :rules="serviceRules" ref="serviceForm" :label-width="80" label-position="left">
        <Row :gutter="20">
          <Col span="24" v-if="!groupId">
            <FormItem :class="{'error-item': groupNameEmpty}">
              <div slot="label"><i class="error-star">*</i> 所属服务组</div>
              <dropdown-add v-model="groupName" placeholder="请选择服务组" buttonText="新增服务组" :list="serviceGroupList" @on-add="groupAdd()" @on-blur="serviceGroupValid" ></dropdown-add>
              <div class="ivu-form-item-error-tip ivu-form-item-error-tip-item">请选择服务组</div>
            </FormItem>
          </Col>
          <Col span="16">
            <FormItem label="服务名称" prop="id">
              <Input v-model.trim="serviceForm.id" placeholder="请输入服务名称" :disabled="isEdit && !clone" ></Input>
            </FormItem>
          </Col>
          <Col span="8">
            <FormItem label="容器数量" prop="replicas">
              <Input v-model.trim="serviceForm.replicas" placeholder="请输入容器数量" @on-blur="changePod"></Input>
              <div class="ivu-form-item-error-tip color-orange" v-if="podWarn">* 0意味着该服务停止！</div>
            </FormItem>
          </Col>
          <Col span="24">
            <FormItem label="镜像" prop="image">
              <Input v-model.trim="serviceForm.image" placeholder="192.168.10.238/dev/mysql:1"></Input>
            </FormItem>
          </Col>
          <Col span="24">
            <FormItem label="服务描述">
              <Input v-model.trim="serviceForm.description" type="textarea" placeholder="请输入服务描述" @on-blur="$limitLen($event, 500)" ></Input>
              <!-- 暂时不用 -->
              <!-- <Checkbox v-model="serviceForm.privilege"> 特权方式运行</Checkbox> -->
            </FormItem>
          </Col>
          <Col span="24">
            <FormItem label="端口映射">
              <port-mapping :ports.sync="serviceForm.ports"></port-mapping>
            </FormItem>
          </Col>
          <Col span="24">
            <FormItem label="访问权">
              <access-right-panel
                v-if="modalVisible"
                :serviceName="serviceForm.id"
                :ports="serviceForm.ports"
                :accessList.sync="accessList"
                @accessAddMinus="accessAddMinus">
              </access-right-panel>
            </FormItem>
          </Col>
          <Col span="24">
            <div class="service-extra">
              <Checkbox v-model="extraFlag.environmentVariable" class="extra-title" @on-change="initServiceExtra('env')"> 环境变量</Checkbox>
              <environment-variable :env.sync="serviceForm.env" :init="extraFlag.environmentVariable" v-if="extraFlag.environmentVariable"></environment-variable>
            </div>
            <div class="service-extra">
              <Checkbox v-model="extraFlag.command" class="extra-title" @on-change="initServiceExtra('command')"> 命令</Checkbox>
              <command :commandForm.sync="commandForm" v-if="extraFlag.command"></command>
            </div>
            <div class="service-extra">
              <Checkbox v-model="extraFlag.configSet" class="extra-title" @on-change="initServiceExtra('configSet')"> 配置集</Checkbox>
              <config-set :configForm.sync="configForm" v-if="extraFlag.configSet"></config-set>
            </div>
            <div class="service-extra">
              <Checkbox v-model="extraFlag.pvc" class="extra-title" @on-change="initServiceExtra('pvc')"> 存储卷</Checkbox>
              <pvc :pvcForm.sync="pvcForm" v-if="extraFlag.pvc"></pvc>
            </div>
            <div class="service-extra">
              <Checkbox v-model="extraFlag.host" class="extra-title" @on-change="initServiceExtra('host')"> 资源配额</Checkbox>
              <host :hostForm.sync="hostForm" v-if="extraFlag.host"></host>
            </div>
            <div class="service-extra">
              <Checkbox v-model="extraFlag.encrpt" :disabled="true" class="extra-title"> 密文</Checkbox>
            </div>
             <div class="service-extra">
              <Checkbox v-model="extraFlag.healthCheck" :disabled="true" class="extra-title"> 健康检查</Checkbox>
            </div>
             <div class="service-extra">
              <Checkbox v-model="extraFlag.stretch" :disabled="true" class="extra-title"> 自动伸缩</Checkbox>
            </div>
          </Col>
        </Row>
      </Form>
    </div>
    <div slot="footer">
      <Button type="warning" @click="serviceAddCancel">取消</Button>
      <Button type="primary" :loading="isAdding" @click="serviceAddConf">确定</Button>
    </div>
  </Modal>
</template>
<script type="text/javascript">
import PortMapping from '@/components/add-service/port-mapping'
import Command from '@/components/add-service/command'
import EnvironmentVariable from '@/components/add-service/environment-variable'
import Pvc from '@/components/add-service/pvc'
import Host from '@/components/add-service/host'
import ConfigSet from '@/components/add-service/config-set'
import AccessRightPanel from '@/components/add-service/access'
import Fetch from '@/api/request'
import DropdownAdd from '@/components/dropdown-add'
import uuid from 'uuid/v4'
export default {
  name: 'ServiceAddModal',
  components: { PortMapping, Command, EnvironmentVariable, Pvc, Host, ConfigSet, DropdownAdd, AccessRightPanel },
  data() {
    const validateName = (rule, value, callback) => {
      var regName = /^(?![A-Z0-9-])(?!.*?-$)[a-z0-9-]{1,}$/
      if (!value) {
        callback(new Error('请输入名称'))
      } else if (!regName.test(value)) {
        callback(new Error('小写字母开头，只能包含小写字母、数字、「-」连字符'))
      } else if (value.length < 4) {
        callback(new Error('最小长度不能少于4位'))
      } else if (value.length > 24) {
        callback(new Error('最大长度不能大于24位'))
      } else {
        callback()
      }
    }
    const validateDescription = (rule, value, callback) => {
      if (value && value.length > 128) {
        callback(new Error('最大长度不能大于128位'))
      } else {
        callback()
      }
    }
    const validateImage = (rule, value, callback) => {
      if (!value) {
        callback(new Error('请输入镜像地址'))
      } else if (value.length < 4) {
        callback(new Error('最小长度不能小于4位'))
      } else if (value.length > 128) {
        callback(new Error('最大长度不能大于128位'))
      } else {
        callback()
      }
    }
    const validateReplicas = (rule, value, callback) => {
      var regReplicas = /^\+?[0-9]$/
      if (!(value + '')) {
        callback(new Error('请输入容器数量'))
      } else if (!regReplicas.test(value)) {
        callback(new Error('请输入0-9的整数'))
      } else {
        callback()
      }
    }
    return {
      serviceForm: {
        id: '',
        replicas: '1',
        image: '',
        description: '',
        privilege: false,
        ports: [],
        command: '',
        args: '',
        hostName: '',
        env: [],
        pvcName: '',
        mountPath: '',
        configMapName: '',
        configMapMountPath: '',
        requestCpu: '',
        cpu: '',
        requestMemory: '',
        memory: '',
        hpaCpuPctFlag: false, // 暂时写死
        hpaMemoryPctFlag: false // 暂时写死
      },
      serviceRules: {
        id: [{required: true, trigger: 'blur', validator: validateName}],
        description: [ { required: false, trigger: 'blur', validator: validateDescription } ],
        image: [ { required: true, trigger: 'blur', validator: validateImage } ],
        replicas: [ { required: true, trigger: 'blur', validator: validateReplicas } ]
      },
      isAdding: false,
      extraFlag: {
        environmentVariable: false,
        command: false,
        configSet: false,
        pvc: false,
        host: false,
        healthCheck: false,
        encrpt: false,
        stretch: false
      },
      groupId: '',
      groupName: '',
      serviceGroupList: [],
      modalVisible: false,
      groupNameEmpty: false,
      isEdit: false,
      clone: false,
      podWarn: false,
      hostValide: true,
      accessList: []
    }
  },
  computed: {
    commandForm: {
      get: function () {
        return {
          command: this.serviceForm.command,
          args: this.serviceForm.args,
          hostName: this.serviceForm.hostName
        }
      },
      set: function (val) {
        this.serviceForm.command = val.command
        this.serviceForm.args = val.args
        this.serviceForm.hostName = val.hostName
      }
    },
    pvcForm: {
      get: function () {
        return {
          pvcName: this.serviceForm.pvcName,
          mountPath: this.serviceForm.mountPath
        }
      },
      set: function (val) {
        this.serviceForm.pvcName = val.pvcName
        this.serviceForm.mountPath = val.mountPath
      }
    },
    configForm: {
      get: function () {
        return {
          configMapName: this.serviceForm.configMapName,
          configMapMountPath: this.serviceForm.configMapMountPath
        }
      },
      set: function (val) {
        this.serviceForm.configMapName = val.configMapName
        this.serviceForm.configMapMountPath = val.configMapMountPath
      }
    },
    hostForm: {
      get: function () {
        return {
          requestCpu: this.serviceForm.requestCpu,
          cpu: this.serviceForm.cpu,
          requestMemory: this.serviceForm.requestMemory,
          memory: this.serviceForm.memory
        }
      },
      set: function (val) {
        this.serviceForm.requestCpu = val.requestCpu
        this.serviceForm.cpu = val.cpu
        this.serviceForm.requestMemory = val.requestMemory
        this.serviceForm.memory = val.memory
        this.hostValide = val.hostValide
      }
    }
  },
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    params: {
      type: Object
    }
  },
  methods: {
    // 访问权修改
    accessAddMinus(params) {
      if (params.add) {
        this.accessList.push(params.access)
      } else {
        this.accessDelete(params.access)
        this.accessList = this.accessList.filter((item) => {
          return item.id !== params.access.id
        })
      }
    },
     // 删除访问权
    accessDelete(access) {
      Fetch.delete({
        url: '/api/environments/' + this.$route.params.environmentId + '/ingresses/' + access.id,
        done: () => {
          this.$Modal.remove()
        }
      }).then((res) => {
        this.$Message.success({
          content: '删除访问权（' + access.id + '）成功！',
          duration: this.DURATION
        })
      })
    },
    // 改变容器数，用于当容器数为0时，显示警告
    changePod() {
      this.podWarn = this.serviceForm.replicas === '0'
    },
    // 新增服务组
    groupAdd() {
      this.$emit('on-add-group')
    },
    // 服务组为空校验
    serviceGroupValid(val) {
      this.groupNameEmpty = !val
    },
    // 初始化服务额外参数
    initServiceExtra(params) {
      if (params === 'env' && !this.extraFlag.environmentVariable) {
        this.serviceForm.env = [{id: uuid(), name: '', value: ''}]
      } else if (params === 'command' && !this.extraFlag.command) {
        this.serviceForm.command = ''
        this.serviceForm.args = ''
        this.serviceForm.hostName = ''
      } else if (params === 'configSet' && !this.extraFlag.configSet) {
        this.serviceForm.configMapName = ''
        this.serviceForm.configMapMountPath = ''
      } else if (params === 'pvc' && !this.extraFlag.pvc) {
        this.serviceForm.pvcName = ''
        this.serviceForm.mountPath = ''
      } else if (params === 'host' && !this.extraFlag.host) {
        this.serviceForm.cpu = ''
        this.serviceForm.requestCpu = ''
        this.serviceForm.memory = ''
        this.serviceForm.requestMemory = ''
      }
    },
    // 确认添加服务
    serviceAddConf() {
      // 在服务组外面添加服务，需先选择服务组
      if (!this.groupId && !this.groupName) {
        return
      }
      // 资源配额校验判断，如果校验不通过不提交
      if (!this.hostValide) {
        return
      }
      if (this.groupName) {
        this.serviceGroupList.forEach(group => {
          if (this.groupName === group.name) {
            this.groupId = group.id
          }
        })
      }

      this.$refs['serviceForm'].validate((valid) => {
        if (valid) {
          // 查看是否具有一个有效端口
          let portsFilter = this.serviceForm.ports.filter((port) => {
            return port.port && port.targetPort
          })
          if (portsFilter.length === 0) {
            this.$Message.warning({
              content: '请至少填写一个端口映射!',
              duration: this.DURATION
            })
            return
          }
          // 去除不符合要求的环境变量(name，value有空)
          let t = []
          this.serviceForm.env.forEach(env => {
            if (env.name.length > 0 && env.value.length > 0) {
              t.push({name: env.name, value: env.value})
            }
          })
          this.serviceForm.env = t
          let params = Object.assign({}, this.serviceForm)
          this.isAdding = true
          params.environmentId = this.$route.params.environmentId
          params.groupId = this.groupId
          // 克隆
          if (this.clone) {
            Fetch.post({
              url: '/api/service/add',
              params: params,
              done: () => {
                this.isAdding = false
              }
            }).then((res) => {
              this.$emit('update:visible', false)
              this.$emit('finish')
              this.$Message.success({
                content: '服务克隆成功！',
                duration: this.DURATION
              })
            })
          } else if (this.isEdit) {
            Fetch.put({
              url: '/api/environments/' + this.$route.params.environmentId + '/groups/' + this.groupId + '/services/' + params.id,
              params,
              done: () => {
                this.isAdding = false
              }
            }).then((res) => {
              this.$Message.success({
                content: '服务' + this.serviceForm.id + '编辑成功！',
                duration: this.DURATION
              })
              this.$emit('update:visible', false)
              this.$emit('finish')
            })
          } else {
            Fetch.post({
              url: '/api/service/add',
              params: params,
              done: () => {
                this.isAdding = false
              }
            }).then((res) => {
              this.$emit('update:visible', false)
              this.$emit('finish')
              this.$Message.success({
                content: '服务' + this.serviceForm.id + '添加成功！',
                duration: this.DURATION
              })
            })
          }
        }
      })
    },
    // 取消添加服务
    serviceAddCancel(params) {
      this.$emit('update:visible', false)
    }
  },
  watch: {
    visible(val) {
      let vm = this
      vm.modalVisible = val
      if (val) {
        vm.groupId = vm.params.groupId
        vm.clone = vm.params.clone
        vm.groupName = ''
        vm.groupNameEmpty = false
        vm.serviceGroupList = vm.params.serviceGroupList ? vm.params.serviceGroupList : []
        vm.$nextTick(function () {
          vm.$refs['serviceForm'].resetFields()
          vm.isEdit = !!vm.params.service
          // 访问权获取
          vm.accessList = []
          if (vm.params.service && vm.params.service.access) {
            vm.accessList.push(vm.params.service.access)
          }
          vm.serviceForm = vm.params.service ? vm.params.service : {
            id: '',
            replicas: '1',
            image: '',
            description: '',
            privilege: false,
            ports: [{
              id: uuid(),
              port: '80',
              targetPort: '80',
              protocol: 'TCP'
            }],
            command: '',
            args: '',
            hostName: '',
            env: [{id: uuid(), name: '', value: ''}],
            pvcName: '',
            mountPath: '',
            configMapName: '',
            configMapMountPath: '',
            requestCpu: '',
            cpu: '',
            requestMemory: '',
            memory: '',
            hpaCpuPctFlag: false, // 暂时写死
            hpaMemoryPctFlag: false, // 暂时写死
            access: []
          }
          let extra = {
            environmentVariable: false,
            command: false,
            configSet: false,
            pvc: false,
            host: false,
            healthCheck: false,
            encrpt: false,
            stretch: false
          }
          // 环境变量处理
          if (vm.serviceForm.env && vm.serviceForm.env.length > 0) {
            extra.environmentVariable = true
            let temp = []
            vm.serviceForm.env.forEach(env => {
              let o = Object.assign({id: uuid()}, env)
              temp.push(o)
            })
            vm.serviceForm.env = temp
          }
          // 映射端口处理
          if (vm.serviceForm.ports && vm.serviceForm.ports.length > 0) {
            let tempPorts = []
            for (let i = 0; i < vm.serviceForm.ports.length; i++) {
              const port = vm.serviceForm.ports[i]
              tempPorts.push({
                id: uuid(),
                port: port.port,
                targetPort: port.targetPort,
                protocol: port.protocol
              })
            }
            vm.serviceForm.ports = tempPorts
          }
          // 命令行处理
          if (vm.serviceForm.command || vm.serviceForm.args) {
            extra.command = true
          }
          if (vm.serviceForm.configMapName || vm.serviceForm.configMapMountPath) {
            extra.configSet = true
          }
          if (vm.serviceForm.pvcName || vm.serviceForm.mountPath) {
            extra.pvc = true
          }
          if (vm.serviceForm.requestMemory || vm.serviceForm.memory || vm.serviceForm.cpu || vm.serviceForm.requestCpu) {
            extra.host = true
          }
          vm.extraFlag = extra
          vm.podWarn = vm.params.service ? vm.params.service.replicas === '0' : false
        })
      }
    },
    params(val) {
      if (val) {
        this.groupId = val.groupId
        this.groupName = ''
        this.groupNameEmpty = false
        this.serviceGroupList = val.serviceGroupList ? val.serviceGroupList : []
        // 通过新增服务组添加了服务组
        if (val.serviceGroupAddObj) {
          this.groupName = val.serviceGroupAddObj.name
        }
      }
    }
  }
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
  .service-params-box {
    min-height: 160px;
    padding-bottom: 10px;
  }
  .service-tabs /deep/ .ivu-tabs-nav .ivu-tabs-tab {
    padding: 8px 14px;
  }
  .modal-add {
    position: relative;
    padding: 10px 50px 10px 20px;
  }
  .button-add {
    .iconfont:hover {
      color: #fff;
    }
  }
  .service-extra {
    .extra-title {
      padding-bottom: 10px;
    }
  }
  .service-group {
    width: 100%;
  }
</style>
